package com.xuecheng.teaching.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.comment.model.dto.CommentDTO;
import com.xuecheng.api.comment.model.dto.CommentReplyDTO;
import com.xuecheng.api.comment.model.qo.CommentConditionModel;
import com.xuecheng.api.comment.model.vo.CommentStatisticsVo;
import com.xuecheng.api.search.model.dto.CoursePubIndexDTO;
import com.xuecheng.api.teaching.model.CompanyDTO;
import com.xuecheng.api.teaching.model.qo.QueryCompanyModel;
import com.xuecheng.common.domain.code.CommonErrorCode;
import com.xuecheng.common.domain.page.PageRequestParams;
import com.xuecheng.common.domain.page.PageVO;
import com.xuecheng.common.domain.response.RestResponse;
import com.xuecheng.common.enums.common.AuditEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.teaching.agent.CommentApiAgent;
import com.xuecheng.teaching.agent.SearchApiAgent;
import com.xuecheng.teaching.common.constant.TeachingErrorCode;
import com.xuecheng.teaching.convert.CompanyConvert;
import com.xuecheng.teaching.entity.Company;
import com.xuecheng.teaching.mapper.CompanyMapper;
import com.xuecheng.teaching.service.CompanyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class CompanyServiceImpl extends ServiceImpl<CompanyMapper, Company> implements CompanyService {

    @Autowired
    private CommentApiAgent commentApiAgent;

    @Autowired
    private SearchApiAgent searchApiAgent;

    public CompanyDTO getByTenantId(Long tenantId) {

        if (tenantId == null || tenantId <= 0) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }

        LambdaQueryWrapper<Company> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(Company::getTenantId, tenantId);

        Company company = this.getOne(queryWrapper);

        return CompanyConvert.INSTANCE.entity2dto(company);

    }

    @Override
    public PageVO<CommentDTO> commentList(PageRequestParams params, CommentConditionModel commentModel, Boolean company) {

        //远程调用comment-service
        RestResponse<PageVO<CommentDTO>> response = commentApiAgent.list(params, commentModel, company);
        //判断远程调用是否成功
        if (!(response.isSuccessful())) {
            ExceptionCast.cast(TeachingErrorCode.E_130601);
        }

        //获取分页数据
        PageVO<CommentDTO> pageVO = response.getResult();

        return pageVO;
    }

    /**
     * 发表评论
     *
     * @param commentDTO
     * @return
     */
    @Override
    @Transactional
    public CommentDTO comment(CommentDTO commentDTO, String userName) {

        // 1.判断关键数据
        if (ObjectUtils.isEmpty(commentDTO)
        ) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }

        if (StringUtils.isEmpty(userName)) {
            ExceptionCast.cast(CommonErrorCode.E_100110);
        }

        if (commentDTO.getStarRank().equals(CommentDTO.NOT_STARRANK)) {
            ExceptionCast.cast(TeachingErrorCode.E_141001);
        }

        // 查询评论所属课程名称
        Long targetId = commentDTO.getTargetId();

        RestResponse<CoursePubIndexDTO> restResponse = searchApiAgent.getCoursePubIndexById4s(targetId);

        if (!restResponse.isSuccessful()) {
            ExceptionCast.castWithCodeAndDesc(restResponse.getCode(), restResponse.getMsg());
        }

        CoursePubIndexDTO result = restResponse.getResult();

        if (ObjectUtils.isEmpty(result)) {
            ExceptionCast.cast(TeachingErrorCode.E_141002);
        }

        Long companyId = result.getCompanyId();

        // 添加关键数据
        commentDTO.setUserName(userName);

        commentDTO.setComeFrom(CommentDTO.COME_FROM);

        commentDTO.setBelongTo(companyId);

        commentDTO.setTargetName(result.getName());

        RestResponse<CommentDTO> response = commentApiAgent.comment(commentDTO);

        if (!response.isSuccessful()) {
            ExceptionCast.cast(TeachingErrorCode.E_141000);
        }

        CommentDTO dto = response.getResult();

        if (ObjectUtils.isEmpty(dto)) {
            ExceptionCast.cast(TeachingErrorCode.E_141000);
        }

        return response.getResult();
    }

    /*
     * 统计
     * */
    @Override
    public CommentStatisticsVo getStatistics(Long coursePubId) {
        //远程调用comment-service
        RestResponse<CommentStatisticsVo> response = commentApiAgent.getStatistics(coursePubId);

        //判断远程调用是否成功
        if (!(response.isSuccessful())) {
            ExceptionCast.cast(TeachingErrorCode.E_130701);
        }

        //获得统计数据
        CommentStatisticsVo commentStatistics = response.getResult();
        return commentStatistics;
    }


    @Override
    public Boolean praise(Long commentId) {
        //评论点赞，远程调用feign接口
        RestResponse<CommentDTO> response = commentApiAgent.praise(commentId);
        Boolean result = response.isSuccessful();
        return result;
    }

    //删除评论
    @Override
    public Boolean deleteComment(Long commentId) {
        RestResponse<CommentDTO> dtoRestResponse = commentApiAgent.delComment(commentId);
        Boolean result = dtoRestResponse.isSuccessful();
        return result;
    }

    /**
     * 批量删除评论
     *
     * @param commentIds
     * @param
     * @return
     */
    @Override
    public Boolean batchDelComment(List<Long> commentIds) {

        // 1.判断关键数据
        if (CollectionUtils.isEmpty(commentIds)
        ) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }

        // 调用 Comment 服务
        RestResponse<Boolean> response = commentApiAgent.batchDelComment(commentIds);

        Boolean result = response.getResult();

        if (ObjectUtils.isEmpty(response) || (!result)) {
            ExceptionCast.cast(TeachingErrorCode.E_141002);
        }

        return result;
    }

    /**
     * 1.判断关键数据
     * companyId  commentId  replyText
     * 2.根据commentId远程调用获得评论数据
     * 判断要回复的评论是否归属于本机构
     * 3.远程调用comment微服务获得评论回复数据并返回
     */
    public CommentReplyDTO commentReply(CommentReplyDTO dto, Long companyId) {

        //1.判断关键数据
        if (ObjectUtils.isEmpty(dto.getCommentId()) ||
                ObjectUtils.isEmpty(dto.getReplyText()) ||
                ObjectUtils.isEmpty(companyId)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //2.根据commentId远程调用获得评论数据
        RestResponse<CommentDTO> commentResponse = commentApiAgent.getCommentById(dto.getCommentId());
        if (!(commentResponse.isSuccessful())) {
            ExceptionCast.castWithCodeAndDesc(commentResponse.getCode(), commentResponse.getMsg());
        }
        CommentDTO commentDTO = commentResponse.getResult();
        if (!(ObjectUtils.nullSafeEquals(companyId, commentDTO.getBelongTo()))) {
            ExceptionCast.cast(TeachingErrorCode.E_132003);
        }
        //3.远程调用comment微服务获得评论回复数据并返回
        RestResponse<CommentReplyDTO> replyResponse = commentApiAgent.reply(dto);
        if (!(replyResponse.isSuccessful())) {
            ExceptionCast.castWithCodeAndDesc(replyResponse.getCode(), replyResponse.getMsg());
        }
        CommentReplyDTO replyDTO = replyResponse.getResult();
        if (ObjectUtils.isEmpty(replyDTO)) {
            ExceptionCast.cast(TeachingErrorCode.E_132004);
        }

        return replyDTO;

    }

    /**
     * 1.判断数据
     * pageNo  pageSize
     * 2.创建查询条件
     * 3.创建分页条件
     * 4.查询机构数据  转为dto封装返回
     *
     * @return
     */
    public PageVO<CompanyDTO> queryCompanyList(PageRequestParams params, QueryCompanyModel model) {
        //1.判断数据
        Long pageNo = params.getPageNo();
        Integer pageSize = params.getPageSize();
        if (pageNo < 1) {
            pageNo = PageRequestParams.DEFAULT_PAGE_NUM;
        }

        if (pageSize < 1) {
            pageSize = PageRequestParams.DEFAULT_PAGE_SIZE;
        }

        //2.创建查询条件
        LambdaQueryWrapper<Company> queryWrapper = new LambdaQueryWrapper<>();
        if (!(ObjectUtils.isEmpty(model.getCompanyName()))) {
            queryWrapper.eq(Company::getName, model.getCompanyName());
        }

        if (!(ObjectUtils.isEmpty(model.getApprovalStatus()))) {

            if (!(AuditEnum.AUDIT_PASTED_STATUS.getCode().equals(model.getApprovalStatus()))) {
                queryWrapper.ne(Company::getApprovalStatus, AuditEnum.AUDIT_PASTED_STATUS.getCode());

            } else {

                queryWrapper.eq(Company::getApprovalStatus, model.getApprovalStatus());
            }
        }

        //3.创建分页条件
        Page<Company> page = new Page<>(pageNo, pageSize);

        //4.查询机构数据  转为dto封装返回
        Page<Company> pageResult = this.page(page, queryWrapper);
        List<Company> companyList = pageResult.getRecords();

        //po-->dto
        List<CompanyDTO> companyDTOS = CompanyConvert.INSTANCE.entitys2dtos(companyList);

        PageVO<CompanyDTO> pageVO = new PageVO<>(companyDTOS, pageResult.getTotal(), pageNo, pageSize);
        return pageVO;
    }

    /**
     * 1.判断关键数据
     * companyId
     * 2.根据 companyId查询机构数据
     * 3.po转为dto返回
     */
    public CompanyDTO getCompanyById(Long companyId) {
        //1.判断关键数据
        if (ObjectUtils.isEmpty(companyId)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //2.根据 companyId查询机构数据
        Company company = this.getById(companyId);
        if (ObjectUtils.isEmpty(company)) {
            ExceptionCast.cast(TeachingErrorCode.E_130506);
        }

        //po--dto
        CompanyDTO companyDTO = CompanyConvert.INSTANCE.entity2dto(company);

        return companyDTO;
    }


    /**
     * 1.判断关键数据
     * companyId  username
     * 2.根据 companyId 查询机构数据
     * 判断机构是否存在
     * 判断机构审核状态 (审核未通过  未审核  才需要审核)
     * 3.对课程进行审核 (修改课程审核状态)
     */
    @Transactional
    public void approveCompany(CompanyDTO companyDTO, String username) {

        //1.判断关键数据
        if (ObjectUtils.isEmpty(companyDTO.getCompanyId()) || StringUtils.isEmpty(username)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //2.根据 companyId 查询机构数据
        Company company = this.getById(companyDTO.getCompanyId());
        //判断机构是否存在
        if (ObjectUtils.isEmpty(company)) {
            ExceptionCast.cast(TeachingErrorCode.E_130504);
        }
        //判断机构审核状态 (审核未通过  未审核  才需要审核)
        if (AuditEnum.AUDIT_PASTED_STATUS.getCode().equals(company.getApprovalStatus())) {
            ExceptionCast.cast(TeachingErrorCode.E_130505);
        }

        //3.对课程进行审核 (修改课程审核状态)
        LambdaUpdateWrapper<Company> updateWrapper = new LambdaUpdateWrapper<>();
        //审核状态
        updateWrapper.set(Company::getApprovalStatus, companyDTO.getApprovalStatus());
        //审核意见
        updateWrapper.set(Company::getApprovalComment, companyDTO.getApprovalComment());
        //审核时间
        updateWrapper.set(Company::getApprovalDate, LocalDateTime.now());
        //审核次数
        Integer approvalNums = company.getApprovalNums();
        updateWrapper.set(Company::getApprovalNums, approvalNums + 1);
        //审核人
        updateWrapper.set(Company::getApprovalPeople, username);
        //修改时间
        updateWrapper.set(Company::getChangeDate, LocalDateTime.now());
        updateWrapper.eq(Company::getId, companyDTO.getCompanyId());

        boolean update = this.update(updateWrapper);
        if (!update) {
            ExceptionCast.cast(TeachingErrorCode.E_130507);
        }
    }

    /**
     * 1.判断关键数据
     * companyId
     * 2.根据 companyId 查询机构数据
     * 判断机构是否存在
     * 3.po转为dto返回
     */
    public CompanyDTO getMyCompany(Long companyId) {
        //1.判断关键数据
        if (ObjectUtils.isEmpty(companyId)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //2.根据 companyId 查询机构数据
        Company company = this.getById(companyId);
        //判断机构是否存在
        if (ObjectUtils.isEmpty(company)) {
            ExceptionCast.cast(TeachingErrorCode.E_130506);
        }

        //3.po转为dto返回
        CompanyDTO companyDTO = CompanyConvert.INSTANCE.entity2dto(company);
        return companyDTO;
    }
}
